package cn.kgm.global;


import cn.kgm.global.impl.*;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Objects;

/**
 * @Version 1.8
 * @Author: Kappi
 * @Date: 2023-11-14 10:59
 * @Description: com.makuku.common.constants.global.GlobalUtil
 */
public class GlobalUtil {

    private final GlobalHandler head;

    private GlobalUtil() {
        head = new HeadGlobal();
        GlobalHandler strGlobal = new StrGlobal();
        GlobalHandler numGlobal = new NumGlobal();
        GlobalHandler bigGlobal = new BigGlobal();
        GlobalHandler tail = new TailGlobal();
        head.setGlobal(strGlobal, String.class)
                .setGlobal(numGlobal, Integer.class)
                .setGlobal(bigGlobal, BigDecimal.class)
                .setGlobal(tail, TailGlobal.class);
    }

    public static <T> T value(String name, Class<T> clazz) {
        return getInstance().getValue(name, clazz);
    }

    public static Object value(String name) {
        return getInstance().getValue(name);
    }

    public static GlobalUtil getInstance() {
        return SingletonGlobalHandler.INSTANCE;
    }

    public Object getValue(String name) {
        GlobalHandler handler = head.global;
        while (true) {
            try {
                return getValue(name, handler.typeClass);
            } catch (RuntimeException e) {
                handler = handler.global;
            }
        }
    }

    public <T> T getValue(String name, Class<T> clazz) {
        try {
            GlobalHandler handler = head;
            while (true) {
                if (Objects.isNull(handler.getTypeClass())
                        || !Objects.equals(handler.getTypeClass(), clazz)) {
                    handler = handler.global;
                    continue;
                }
                if (handler.getClass().equals(TailGlobal.class)) {
                    throw new RuntimeException("不存在此类型的通用常量【" + clazz.getName() + "】");
                }
                return (T) getValue(name, handler);
            }
        } catch (NoSuchFieldException ne) {
            throw new RuntimeException(String.format("当前 name[%s] 没有具体的 常量 处理", name));
        }
    }

    public Object getValue(String name, GlobalHandler handler) throws NoSuchFieldException {
        Field field;
        try {
            field = handler.globalClass.getDeclaredField(name);
            field.setAccessible(true);
            return field.get(handler);
        } catch (NoSuchFieldException | IllegalAccessException ne) {
            throw new RuntimeException("当前 name[" + name + "] 没有具体的 常量 处理");
        }
    }

    private static class SingletonGlobalHandler {
        private static final GlobalUtil INSTANCE = new GlobalUtil();
    }
}
